package com.luck.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.CompletableFuture;

public class CompletableFutureUtil {
    private static Logger logger = LoggerFactory.getLogger(CompletableFutureUtil.class);

    public static void main(String[] args) throws Exception{
        //logger.info("有返回结果: " + CompletableFutureUtil.asyncString().get());
        //logger.info("没有返回结果: " + CompletableFutureUtil.asyncVoid().get());
        //logger.info("全部执行完毕返回: " + CompletableFutureUtil.asyncAll().get());
        //logger.info("任意执行完毕返回: " + CompletableFutureUtil.asyncAny().get());
        //logger.info("任务1执行完成后执行任务2(返回结果为任务1): " + CompletableFutureUtil.whenComplete().get());
        logger.info("任务1执行完成后执行任务2(返回结果为任务2): " + CompletableFutureUtil.thenApply().get());
        logger.info("任务1执行完成后执行任务2(返回结果为任务2): " + CompletableFutureUtil.thenCompose().get());
        //logger.info("任务1执行完成后执行任务2(返回结果为任务2) 可处理异常: " + CompletableFutureUtil.handle().get());
        //logger.info("任务1执行完成后执行任务2(无返回结果): " + CompletableFutureUtil.thenAccept().get());
        //logger.info("任务1执行完成后执行任务2(无返回结果)不关注任务1结果: " + CompletableFutureUtil.thenRun().get());
        //logger.info("合并任务，有结果：" + CompletableFutureUtil.thenCombine().get());
        //logger.info("合并任务结果，无结果：" + CompletableFutureUtil.thenAcceptBoth().get());
        //logger.info("任意执行完毕，进行下一步 - 接收结果 - 有返回结果：" + CompletableFutureUtil.applyToEither().get());
        //logger.info("任意执行完毕，进行下一步 - 接收结果 - 无返回结果：" + CompletableFutureUtil.acceptEither().get());
        //logger.info("任意执行完毕，进行下一步 - 不接收结果：" + CompletableFutureUtil.runAfterEither().get());
        //logger.info("都执行结束，进行下一步 - 不接收结果: " + CompletableFutureUtil.runAfterBoth().get());
        Thread.sleep(2000);
    }


    // 执行异步 -- 支持返回值
    private static CompletableFuture<String> asyncString(){
        return CompletableFuture
                .supplyAsync(() -> CompletableFutureUtil.executeMethod("supplyAsync"));
    }
    // 执行异步 -- 不支持返回值
    private static CompletableFuture<Void> asyncVoid() {
        return CompletableFuture
                .runAsync(() -> CompletableFutureUtil.executeMethod("runAsync"));
    }

    // 全部执行完毕返回
    private static CompletableFuture<Void> asyncAll() {
        return CompletableFuture.allOf(asyncString(), asyncVoid());
    }

    // 任意一个执行完毕返回
    private static CompletableFuture<Object> asyncAny() {
        return CompletableFuture.anyOf(asyncString(), asyncVoid());
    }

    // 任务1 执行完毕后 执行2 -- 不影响返回结果
    private static CompletableFuture<String> whenComplete() {
        CompletableFuture<String> stringCompletableFuture = asyncString();
        CompletableFuture<String> stringCompletableFuture1 = stringCompletableFuture.whenComplete((a, b) -> {
            a = "whenComplete处理返回结果";
            logger.info("任务 asyncString 执行完毕: 结果" + a);
        });
        CompletableFuture<String> exceptionally = stringCompletableFuture.exceptionally((a) -> {
            logger.info("任务 asyncString 执行失败:" + a.getMessage());
            return null;
        });
        return stringCompletableFuture1;
    }

    // 任务1 执行完成后 执行2 -- 影响返回结果 -- 串行化
    private static CompletableFuture<String> thenApply() {
        CompletableFuture<String> stringCompletableFuture = asyncString();
        return stringCompletableFuture.thenApply((a) -> {
            logger.info("任务 asyncString 执行完毕: 结果" + a);
            return "thenApply处理返回结果" + a;
        });
    }

    // 任务1 执行完成后 执行2 -- 影响返回结果 -- 串行化
    private static CompletableFuture<String> thenCompose () {
        CompletableFuture<String> stringCompletableFuture = asyncString();
        return stringCompletableFuture.thenCompose(param -> CompletableFuture.supplyAsync(() -> {
            logger.info("任务 asyncString 执行完毕: 结果" + param);
            return "thenApply处理返回结果" + param;
        }));

    }

    // 任务1 执行完成后 执行2 -- 影响返回结果 -- 可处理异常
    private static CompletableFuture<String> handle() {
        CompletableFuture<String> stringCompletableFuture = asyncString();
        return stringCompletableFuture.handle((a, b) -> {
            if (b != null) {
                return "异常" + b.getMessage();
            }
            return "handle处理返回结果" + a;
        });
    }

    // 任务1 执行完成后 执行2 -- 无返回结果 -- 接收任务1的值
    private static CompletableFuture<Void> thenAccept() {
        CompletableFuture<String> stringCompletableFuture = asyncString();
        return stringCompletableFuture.thenAccept((a) -> {
            logger.info("任务 asyncString 执行完毕: 结果" + a);
        });
    }

    // 任务1 执行完成后 执行2 -- 无返回结果 -- 不接收任务1的值
    private static CompletableFuture<Void> thenRun() {
        CompletableFuture<String> stringCompletableFuture = asyncString();
        return stringCompletableFuture.thenRun(() -> {
            logger.info("任务 asyncString 执行完毕, 不关注结果." );
        });
    }

    // 合并任务 -- 并返回结果
    private static CompletableFuture<String> thenCombine() {
        CompletableFuture<String> stringCompletableFuture = asyncString();
        return stringCompletableFuture.thenCombine(asyncVoid(), (a, b) -> {
            logger.info("a:{}, b:{}", a, b);
            return "a+b:" + a + b;
        });
    }

    // 合并任务 -- 无返回结果
    private static CompletableFuture<Void> thenAcceptBoth() {
        CompletableFuture<String> stringCompletableFuture = asyncString();
        return stringCompletableFuture.thenAcceptBoth(asyncString(), (a, b) -> {
            logger.info("a:{}, b:{}", a, b);
        });
    }

    // 任意执行完毕，进行下一步 - 接收结果 - 有返回结果
    private static CompletableFuture<String> applyToEither() {
        CompletableFuture<String> stringCompletableFuture = asyncString();
        return stringCompletableFuture.applyToEither(asyncString(), (a) -> {
            logger.info("执行快的结果：{}", a);
            return "执行快的结果:" + a;
        });
    }

    // 任意执行完毕，进行下一步 - 接收结果 - 无返回结果
    private static CompletableFuture<Void> acceptEither() {
        CompletableFuture<String> stringCompletableFuture = asyncString();
        return stringCompletableFuture.acceptEither(asyncString(), (a) -> {
            logger.info("执行快的结果：{}", a);
        });
    }

    // 任意执行完毕，进行下一步 - 不接收结果
    private static CompletableFuture<Void> runAfterEither() {
        CompletableFuture<String> stringCompletableFuture = asyncString();
        return stringCompletableFuture.runAfterEither(asyncString(), () -> {
            logger.info("已经有任务执行结束");
        });
    }

    // 都执行结束，进行下一步 - 不接收结果
    private static CompletableFuture<Void> runAfterBoth() {
        CompletableFuture<String> stringCompletableFuture = asyncString();
        return stringCompletableFuture.runAfterBoth(asyncString(), () -> {
            logger.info("任务全部执行结束");
        });
    }







    private static String executeMethod(String param) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //System.out.println("executeMethod -- > " + param);
        logger.info("executeMethod -- > " + param);
        return param;
    }
}
